#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import print_function
import os
import copy
import unittest
import uuid
import tempfile

import requests

#: movie folder
MOVIE_FOLDER = '/media/hdd/movie'

#: the main .ts file
MAIN_TS_FILE = u"{dir}/20170830 1650 - TNT Serie HD (S) - Animal Kingdom - S\u00fcndenbock.ts".format(
	dir=MOVIE_FOLDER)

EXPECTED_FILES = [
	u"{dir}/20170830 1650 - TNT Serie HD (S) - Animal Kingdom - S\u00fcndenbock.eit".format(
		dir=MOVIE_FOLDER),
	MAIN_TS_FILE,
	u"{dir}/20170830 1650 - TNT Serie HD (S) - Animal Kingdom - S\u00fcndenbock.ts.ap".format(
		dir=MOVIE_FOLDER),
	u"{dir}/20170830 1650 - TNT Serie HD (S) - Animal Kingdom - S\u00fcndenbock.ts.cuts".format(
		dir=MOVIE_FOLDER),
	u"{dir}/20170830 1650 - TNT Serie HD (S) - Animal Kingdom - S\u00fcndenbock.ts.meta".format(
		dir=MOVIE_FOLDER),
]

ENV_VAR = "ENIGMA2_HTTP_API_HOST"

ENV_VAL_FALLBACK = "127.0.0.1"

EXPECTED_MOVIE_ITEM = {
	u'filename_stripped': u'20170830 1650 - TNT Serie HD (S) - Animal Kingdom - S\xfcndenbock.ts',
	u'description': u'S\xfcndenbock',
	u'tags': u'',
	u'filesize': 0,
	u'filesize_readable': u'',
	u'serviceref': u'1:0:0:0:0:0:0:0:0:0:/media/hdd/movie/20170830 1650 - TNT Serie HD (S) - Animal Kingdom - S\xfcndenbock.ts',
	u'filename': u'/media/hdd/movie/20170830 1650 - TNT Serie HD (S) - Animal Kingdom - S\xfcndenbock.ts',
	u'eventname': u'Animal Kingdom',
	u'length': u'?:??',
	u'servicename': u'TNT Serie HD (S)',
	u'begintime': u'30.8., 16:50',
	u'fullname': u'1:0:0:0:0:0:0:0:0:0:/media/hdd/movie/20170830 1650 - TNT Serie HD (S) - Animal Kingdom - S\xfcndenbock.ts',
	u'recordingtime': 1504104600,
	u'descriptionExtended': u'1. Staffel, Folge 5: XXXXX XXXXXXXXX XXXX XXXXXX D\xe4mxxxx XX xxxxxxXx XXX XXXXXXX xxxx XXXX XXXXX XX XXXXXXX XXX xxxx XX XXXXXXXX XXXXXXX XXXXXXX x\xe4xxxx XXX xxx XXXXX xxxx xxxxx XXX xxx XXXXXXX XXXX xx XXX XXXXX Xp\xfclxx X\xf6xxXXX X XXXX XXX XXXXXX XXXxxxxx xxx xxx xxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 50 Min.\n2016.\nAb 12 Jahren',
	u'lastseen': 0
}


class MoviefilesTestCase(unittest.TestCase):
	"""
	This test suite shall be used to verify that current and future
	implementations of movie listing classes or functions generate the
	expected values for provided example files.

	The example files are stripped down copies of files generated by
	an enigma2 device.
	"""
	maxDiff = None

	def setUp(self):
		self.test_filename = uuid.uuid4().hex + '-test.file'
		self.test_file = tempfile.mktemp()
		with open(self.test_file, "wb") as tgt:
			tgt.write("TEST1234")
		self.enigma2_host = os.environ.get(ENV_VAR, ENV_VAL_FALLBACK)
		self.file_controller_url = "http://{netloc}/fs?dir={dir}".format(
			netloc=self.enigma2_host, dir=MOVIE_FOLDER)
		self.api_controller_url = "http://{netloc}/api/movielist".format(
			netloc=self.enigma2_host)
		self.file_url = 'http://{host}/fs'.format(host=self.enigma2_host)
		self.testfile_upload_url = "http://{netloc}/fs{dir}".format(
			netloc=self.enigma2_host, dir=MOVIE_FOLDER)

	def testFilesResponseByFileController(self):
		req = requests.get(self.file_controller_url)
		self.assertTrue(req.status_code, 200)

		data = req.json()
		self.assertTrue(len(data) >= 1)
		self.assertTrue(len(set(data.keys()) & set(['Result', 'result'])) == 1)
		files = set(copy.copy(EXPECTED_FILES))
		common_files = set(data['files']) & files
		self.assertEqual(files, common_files)

	def testFilesResponseByApiController(self):
		req = requests.get(self.api_controller_url)
		self.assertTrue(req.status_code, 200)

		raw_data = req.json()
		data = raw_data['movies']
		found = 0
		movie_item = None
		for item in data:
			if item['filename'] == MAIN_TS_FILE:
				found += 1
				movie_item = item
		self.assertEqual(1, found)
		self.assertEqual("Animal Kingdom", movie_item['eventname'])
		self.assertEqual(movie_item, EXPECTED_MOVIE_ITEM)

	def testUpload(self):
		files = {
			"data": open(self.test_file, "rb")
		}
		params = {
			"filename": self.test_filename,
		}

		# upload file
		req = requests.post(self.testfile_upload_url, params=params, files=files)
		self.assertEqual(200, req.status_code)

		# does uploaded file exist?
		req = requests.get(self.testfile_upload_url)
		self.assertTrue(req.status_code, 200)

		data = req.json()
		test_filename_remote = u"{dir}/{filename}".format(
			dir=MOVIE_FOLDER, filename=self.test_filename)
		self.assertTrue(test_filename_remote in data['files'])

		# delete uploaded file
		test_filename_remote_url = self.testfile_upload_url + '/' + self.test_filename
		req = requests.delete(test_filename_remote_url)
		self.assertTrue(req.status_code, 200)

		# we expect that the uploaded file does not exist any more
		req = requests.get(test_filename_remote_url)
		self.assertTrue(req.status_code, 404)


def dump_disclaimer(tow_files=False):
	print("In order for this test to work the environment variable")
	print(">>> {var: ^70} <<<".format(var=ENV_VAR))
	print("needs to be set to the hostname/network location of an "
		  "enigma2 device reachable by this script!")
	print("If this is not the case, the fallback value")
	print(">>> {val: ^70} <<<".format(val=ENV_VAL_FALLBACK))
	print("will be used!")
	if tow_files:
		print("")
		print("Following example files need to be put in {dir}:".format(
			dir=MOVIE_FOLDER))
		print("")
		for file_item in EXPECTED_FILES:
			print("* {!r}".format(file_item))
	print("")
	print("We will be using the network location {val!r} for this test".format(
		val=os.environ.get(ENV_VAR, ENV_VAL_FALLBACK)))
	print("")
	print("")


if __name__ == '__main__':
	dump_disclaimer(tow_files=True)
	unittest.main()
